Philly Crime Data

Reading in Data

We first read in two data sets called “philly” representing several different values having to due with crimes that have occurred in the Philadelphia area since 2015. “Philly” has 15520 observations and 18 total variables.

philly  <- na.omit(st_read("https://pengdsci.github.io/STA553VIZ/w08/PhillyShootings.geojson"))
phillyNeighbor  <- st_read("https://pengdsci.github.io/STA553VIZ/w08/Neighborhoods_Philadelphia.geojson")

Data Summaries

head(philly)
Simple feature collection with 6 features and 21 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: -75.10962 ymin: 40.01166 xmax: -75.08552 ymax: 40.01489
Geodetic CRS:  WGS 84
  objectid year         dc_key code               date_     time race sex age
1 12728033 2016 201615054780.0  400 2016-06-06 20:00:00 12:15:00    B   M  19
2 12728034 2016 201615117555.0  300 2016-12-03 19:00:00 05:43:00    B   M  38
3 12728035 2018 201815093657.0  400 2018-10-13 20:00:00 21:02:00    B   M  31
4 12728036 2020 202015094989.0  400 2020-12-01 19:00:00 17:12:00    B   M  23
5 12728037 2018 201824100255.0  400 2018-11-08 19:00:00 04:29:00    B   M  27
6 12728038 2019 201924106228.0  400 2019-10-27 20:00:00 04:10:00    W   M  22
     wound officer_involved offender_injured offender_deceased
1     Hand                N                N                 N
2    Chest                N                N                 N
3 Multiple                N                N                 N
4     Hand                N                N                 N
5      Arm                N                N                 N
6 Multiple                N                N                 N
                      location latino   point_x  point_y dist inside outside
1     4600 BLOCK Frankford Ave      0 -75.08552 40.01489   15      0       1
2     4600 BLOCK Frankford Ave      0 -75.08552 40.01489   15      0       1
3     4600 BLOCK Frankford Ave      0 -75.08552 40.01489   15      0       1
4     4600 BLOCK FRANKFORD AVE      0 -75.08552 40.01489   15      0       1
5 900 BLOCK E Hunting Park Ave      0 -75.10962 40.01167   24      0       1
6 900 BLOCK E HUNTING PARK AVE      1 -75.10962 40.01167   24      0       1
  fatal                   geometry
1     0 POINT (-75.08552 40.01489)
2     0 POINT (-75.08552 40.01489)
3     1 POINT (-75.08552 40.01489)
4     0 POINT (-75.08552 40.01489)
5     0 POINT (-75.10962 40.01167)
6     0 POINT (-75.10962 40.01167)
head(phillyNeighbor)
Simple feature collection with 6 features and 8 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: -75.28027 ymin: 39.96271 xmax: -75.01684 ymax: 40.09464
Geodetic CRS:  WGS 84
                  name              listname              mapname shape_leng
1       PENNYPACK_PARK        Pennypack Park       Pennypack Park   87084.29
2            OVERBROOK             Overbrook            Overbrook   57004.92
3 GERMANTOWN_SOUTHWEST Germantown, Southwest Southwest Germantown   14880.74
4        EAST_PARKSIDE         East Parkside        East Parkside   10885.78
5         GERMANY_HILL          Germany Hill         Germany Hill   13041.94
6      MOUNT_AIRY_EAST      Mount Airy, East      East Mount Airy   28845.55
  shape_area cartodb_id          created_at          updated_at
1   60140756          9 2013-03-19 13:41:50 2013-03-19 13:41:50
2   76924995        138 2013-03-19 13:41:50 2013-03-19 13:41:50
3   14418666         59 2013-03-19 13:41:50 2013-03-19 13:41:50
4    4231000        129 2013-03-19 13:41:50 2013-03-19 13:41:50
5    6949968         49 2013-03-19 13:41:50 2013-03-19 13:41:50
6   43152470          6 2013-03-19 13:41:50 2013-03-19 13:41:50
                        geometry
1 MULTIPOLYGON (((-75.05645 4...
2 MULTIPOLYGON (((-75.22719 3...
3 MULTIPOLYGON (((-75.16208 4...
4 MULTIPOLYGON (((-75.19931 3...
5 MULTIPOLYGON (((-75.22722 4...
6 MULTIPOLYGON (((-75.18088 4...

Mapping

Now, we can create a leaflet map looking at fatal versus non-fatal crimes that occured in Philadelphia in the year 2023 by using the “color” function once again. The color is dependent on whether or not a crime was labeled as “Fatal” or “Nonfatal”. So, each category will have a specific color, representing the type of crime (fatal vs. nonfatal) that occurred at the time. The map is similar to the previous maps above in which each circle point represents a specific crime. Hovering over a point will give the “Neighborhood”, “Date”, “Race”, and “Sex”, “Age”, and “Street” for that specific crime.

library(leaflet)
library(sf)
library(htmltools)
library(dplyr)
## Create sf object
philly_sf <- st_as_sf(philly, coords = c("point_x", "point_y"), crs = 4326)

# Define color palette for fatal and non-fatal crimes
pal <- leaflet::colorFactor(
  palette = c("red", "gold"), 
  domain = c("Fatal", "Non-Fatal")
)

fatal_color <- "red"
non_fatal_color <- "gold"

map <- leaflet(philly) %>%
  addTiles() %>%
  addCircleMarkers(
    ~point_x, ~point_y,
    color = ifelse(philly$fatal == 1, fatal_color, non_fatal_color),
   radius = 5,
    popup = ~paste("Object ID: ", objectid,
                   "Year: ", year,
                   "Race: ", race,
                   "Sex: ", sex,
                   "Age: ", age,
                   "Wound: ", wound,
                   "Location: ", location),
    labelOptions = labelOptions(
      direction = "auto"
    )
  ) %>%
  addLegend(
    position = "bottomright",
    colors = c(fatal_color, non_fatal_color),
    labels = c("Fatal", "Non-Fatal"),
    title = "Crime Type"
  ) %>%
  addScaleBar() %>%
  addControl(
    html = "<h4>Philadelphia Crime Locations (2015-2024)</h4>",
    position = "topright"
  )%>%
  setView(lng = -75.1527, lat = 39.9707, zoom = 11) %>%
  addProviderTiles(providers$Esri.WorldGrayCanvas) %>%
    addPolygons(data = phillyNeighbor,
              color = 'skyblue',
              weight = 1)  %>%
  addCircleMarkers(data = philly_sf,
                   radius = 5,
                   color = ~pal(fatal),
                   stroke = FALSE, 
                   fillOpacity = 0.5,
                   clusterOptions = markerClusterOptions(maxClusterRadius = 40)) %>%
  # Adding images to the map
  addMarkers(lng = -75.1652, lat = 39.9526, popup = '<img src="https://pengdsci.github.io/STA553VIZ/w08/PhillyCityHall.jpg" width="200" height="200">') %>%
  # HTML style for the map title
  addControl(HTML('<div class="leaflet-control.map-title">Philadelphia Crime Locations (2015-2024)</div>'), position = "topright") %>%
  addLayersControl(baseGroups = c('Dark', 'DarkLabel', 'Esri'),
                   overlayGroups = c("Crime Data"),
                   options = layersControlOptions(collapsed = TRUE))
  

# Display the map
map
LS0tDQp0aXRsZTogIk1vcmUgTWFwcGluZyINCmF1dGhvcjogIkVkd2FyZCBDb2xlbWFuIg0KZGF0ZTogIldlc3QgQ2hlc3RlciBVbml2ZXJzaXR5Ig0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50OiANCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICBzbW9vdGhfc2Nyb2xsOiB5ZXMNCiAgICB0aGVtZTogbHVtZW4NCmVkaXRvcl9vcHRpb25zOg0KICBjaHVua19vdXRwdXRfdHlwZTogaW5saW5lDQotLS0NCg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCg0KZGl2I1RPQyBsaSB7DQogICAgbGlzdC1zdHlsZTpub25lOw0KICAgIGJhY2tncm91bmQtY29sb3I6bGlnaHRncmF5Ow0KICAgIGJhY2tncm91bmQtaW1hZ2U6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDpub25lOw0KICAgIGJhY2tncm91bmQtcG9zaXRpb246MDsNCiAgICBmb250LWZhbWlseTogQXJpYWwsIEhlbHZldGljYSwgc2Fucy1zZXJpZjsNCiAgICBjb2xvcjogIzc4MGMwYzsNCn0NCg0KaDEudGl0bGUgew0KICBmb250LXNpemU6IDI0cHg7DQogIGNvbG9yOiBEYXJrUmVkOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQogIGZvbnQtZmFtaWx5OiBBcmlhbCwgSGVsdmV0aWNhLCBzYW5zLXNlcmlmOw0KICBmb250LXZhcmlhbnQtY2Fwczogbm9ybWFsOw0KfQ0KaDQuYXV0aG9yIHsgDQogICAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmg0LmRhdGUgeyANCiAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgY29sb3I6IERhcmtCbHVlOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQpoMSB7IA0KICAgIGZvbnQtc2l6ZTogMjJweDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQpoMiB7IA0KICAgIGZvbnQtc2l6ZTogMThweDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoMyB7IA0KICAgIGZvbnQtc2l6ZTogMThweDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoNCB7DQogICAgZm9udC1zaXplOiAxOHB4Ow0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBkYXJrcmVkOw0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCg0KLyogVGFiIGZlYXR1cmVzICovDQoubmF2PmxpPmEgew0KICAgIHBvc2l0aW9uOiByZWxhdGl2ZTsNCiAgICBkaXNwbGF5OiBibG9jazsNCiAgICBwYWRkaW5nOiAycHggMTVweDsNCiAgICBjb2xvcjogIzk5MDAwMDsNCn0NCi5uYXYtcGlsbHM+bGkuYWN0aXZlPmEsIC5uYXYtcGlsbHM+bGkuYWN0aXZlPmE6aG92ZXIsIC5uYXYtcGlsbHM+bGkuYWN0aXZlPmE6Zm9jdXMgew0KICAgIGNvbG9yOiAjZmZmZmZmOw0KICAgIGJhY2tncm91bmQtY29sb3I6ICM5OTAwMDA7DQp9DQovKg0KbmF2LXBpbGxzPmxpOm50aC1jaGlsZCgyKSB7DQogICAgYmFja2dyb3VuZDogZ3JlZW47DQogfQ0KICovDQo8L3N0eWxlPg0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRSwgY29tbWVudD1OQX0NCm9wdGlvbnMocmVwb3MgPSBsaXN0KENSQU49Imh0dHA6Ly9jcmFuLnJzdHVkaW8uY29tLyIpKQ0KaWYgKCFyZXF1aXJlKCJ0aWR5dmVyc2UiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIikNCiAgIGxpYnJhcnkodGlkeXZlcnNlKQ0KfQ0KaWYgKCFyZXF1aXJlKCJrbml0ciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJrbml0ciIpDQogICBsaWJyYXJ5KGtuaXRyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJjb3dwbG90IikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImNvd3Bsb3QiKQ0KICAgbGlicmFyeShjb3dwbG90KQ0KfQ0KaWYgKCFyZXF1aXJlKCJsYXRleDJleHAiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygibGF0ZXgyZXhwIikNCiAgIGxpYnJhcnkobGF0ZXgyZXhwKQ0KfQ0KaWYgKCFyZXF1aXJlKCJwbG90bHkiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygicGxvdGx5IikNCiAgIGxpYnJhcnkocGxvdGx5KQ0KfQ0KaWYgKCFyZXF1aXJlKCJnYXBtaW5kZXIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygiZ2FwbWluZGVyIikNCiAgIGxpYnJhcnkoZ2FwbWluZGVyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJwbmciKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoInBuZyIpICAgIA0KICAgIGxpYnJhcnkoInBuZyIpDQp9DQppZiAoIXJlcXVpcmUoIlJDdXJsIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJSQ3VybCIpICAgIA0KICAgIGxpYnJhcnkoIlJDdXJsIikNCn0NCmlmICghcmVxdWlyZSgiY29sb3VycGlja2VyIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJjb2xvdXJwaWNrZXIiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgiY29sb3VycGlja2VyIikNCn0NCmlmICghcmVxdWlyZSgiZ2dhbmltYXRlIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJnZ2FuaW1hdGUiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgiZ2dhbmltYXRlIikNCn0NCmlmICghcmVxdWlyZSgiZ2lmc2tpIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJnaWZza2kiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgiZ2lmc2tpIikNCn0NCmlmICghcmVxdWlyZSgibWFnaWNrIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJtYWdpY2siKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgibWFnaWNrIikNCn0NCmlmICghcmVxdWlyZSgiZ3JEZXZpY2VzIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJnckRldmljZXMiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgiZ3JEZXZpY2VzIikNCn0NCmlmICghcmVxdWlyZSgianBlZyIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygianBlZyIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJqcGVnIikNCn0NCmlmICghcmVxdWlyZSgiZ2dyaWRnZXMiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoImdncmlkZ2VzIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImdncmlkZ2VzIikNCn0NCmlmICghcmVxdWlyZSgicGx5ciIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygicGx5ciIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJwbHlyIikNCn0NCmlmICghcmVxdWlyZSgiZ2dpcmFwaCIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiZ2dpcmFwaCIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJnZ2lyYXBoIikNCn0NCmlmICghcmVxdWlyZSgiaGlnaGNoYXJ0ZXIiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoImhpZ2hjaGFydGVyIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImhpZ2hjaGFydGVyIikNCn0NCmlmICghcmVxdWlyZSgiZm9yZWNhc3QiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoImZvcmVjYXN0IikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImZvcmVjYXN0IikNCn0NCmlmICghcmVxdWlyZSgibGVhZmxldCIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygibGVhZmxldCIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJsZWFmbGV0IikNCn0NCmlmICghcmVxdWlyZSgic2YiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoInNmIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoInNmIikNCn0NCiMjIA0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5nID0gRkFMU0UsICAgDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gVFJVRSwgICANCiAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgY29tbWVudCA9IE5BKQ0KYGBgDQoNCiMgUGhpbGx5IENyaW1lIERhdGENCiMjIFJlYWRpbmcgaW4gRGF0YQ0KICBXZSBmaXJzdCByZWFkIGluIHR3byBkYXRhIHNldHMgY2FsbGVkICJwaGlsbHkiIHJlcHJlc2VudGluZyBzZXZlcmFsIGRpZmZlcmVudCB2YWx1ZXMgaGF2aW5nIHRvIGR1ZSB3aXRoIGNyaW1lcyB0aGF0IGhhdmUgb2NjdXJyZWQgaW4gdGhlIFBoaWxhZGVscGhpYSBhcmVhIHNpbmNlIDIwMTUuICJQaGlsbHkiIGhhcyAxNTUyMCBvYnNlcnZhdGlvbnMgYW5kIDE4IHRvdGFsIHZhcmlhYmxlcy4NCmBgYHtyLCBjb21tZW50PU5BLCByZXN1bHRzPUZBTFNFfQ0KcGhpbGx5ICA8LSBuYS5vbWl0KHN0X3JlYWQoImh0dHBzOi8vcGVuZ2RzY2kuZ2l0aHViLmlvL1NUQTU1M1ZJWi93MDgvUGhpbGx5U2hvb3RpbmdzLmdlb2pzb24iKSkNCnBoaWxseU5laWdoYm9yICA8LSBzdF9yZWFkKCJodHRwczovL3Blbmdkc2NpLmdpdGh1Yi5pby9TVEE1NTNWSVovdzA4L05laWdoYm9yaG9vZHNfUGhpbGFkZWxwaGlhLmdlb2pzb24iKQ0KYGBgDQoNCiMjIERhdGEgU3VtbWFyaWVzDQpgYGB7cn0NCmhlYWQocGhpbGx5KQ0KaGVhZChwaGlsbHlOZWlnaGJvcikNCmBgYA0KDQoNCiMjIE1hcHBpbmcNCiAgTm93LCB3ZSBjYW4gY3JlYXRlIGEgbGVhZmxldCBtYXAgbG9va2luZyBhdCBmYXRhbCB2ZXJzdXMgbm9uLWZhdGFsIGNyaW1lcyB0aGF0IG9jY3VyZWQgaW4gUGhpbGFkZWxwaGlhIGluIHRoZSB5ZWFyIDIwMjMgYnkgdXNpbmcgdGhlICJjb2xvciIgZnVuY3Rpb24gb25jZSBhZ2Fpbi4gVGhlIGNvbG9yIGlzIGRlcGVuZGVudCBvbiB3aGV0aGVyIG9yIG5vdCBhIGNyaW1lIHdhcyBsYWJlbGVkIGFzICJGYXRhbCIgb3IgIk5vbmZhdGFsIi4gU28sIGVhY2ggY2F0ZWdvcnkgd2lsbCBoYXZlIGEgc3BlY2lmaWMgY29sb3IsIHJlcHJlc2VudGluZyB0aGUgdHlwZSBvZiBjcmltZSAoZmF0YWwgdnMuIG5vbmZhdGFsKSB0aGF0IG9jY3VycmVkIGF0IHRoZSB0aW1lLiBUaGUgbWFwIGlzIHNpbWlsYXIgdG8gdGhlIHByZXZpb3VzIG1hcHMgYWJvdmUgaW4gd2hpY2ggZWFjaCBjaXJjbGUgcG9pbnQgcmVwcmVzZW50cyBhIHNwZWNpZmljIGNyaW1lLiBIb3ZlcmluZyBvdmVyIGEgcG9pbnQgd2lsbCBnaXZlIHRoZSAiTmVpZ2hib3Job29kIiwgIkRhdGUiLCAiUmFjZSIsIGFuZCAiU2V4IiwgIkFnZSIsIGFuZCAiU3RyZWV0IiBmb3IgdGhhdCBzcGVjaWZpYyBjcmltZS4NCmBgYHtyLCBjb21tZW50PU5BfQ0KbGlicmFyeShsZWFmbGV0KQ0KbGlicmFyeShzZikNCmxpYnJhcnkoaHRtbHRvb2xzKQ0KbGlicmFyeShkcGx5cikNCiMjIENyZWF0ZSBzZiBvYmplY3QNCnBoaWxseV9zZiA8LSBzdF9hc19zZihwaGlsbHksIGNvb3JkcyA9IGMoInBvaW50X3giLCAicG9pbnRfeSIpLCBjcnMgPSA0MzI2KQ0KDQojIERlZmluZSBjb2xvciBwYWxldHRlIGZvciBmYXRhbCBhbmQgbm9uLWZhdGFsIGNyaW1lcw0KcGFsIDwtIGxlYWZsZXQ6OmNvbG9yRmFjdG9yKA0KICBwYWxldHRlID0gYygicmVkIiwgImdvbGQiKSwgDQogIGRvbWFpbiA9IGMoIkZhdGFsIiwgIk5vbi1GYXRhbCIpDQopDQoNCmZhdGFsX2NvbG9yIDwtICJyZWQiDQpub25fZmF0YWxfY29sb3IgPC0gImdvbGQiDQoNCm1hcCA8LSBsZWFmbGV0KHBoaWxseSkgJT4lDQogIGFkZFRpbGVzKCkgJT4lDQogIGFkZENpcmNsZU1hcmtlcnMoDQogICAgfnBvaW50X3gsIH5wb2ludF95LA0KICAgIGNvbG9yID0gaWZlbHNlKHBoaWxseSRmYXRhbCA9PSAxLCBmYXRhbF9jb2xvciwgbm9uX2ZhdGFsX2NvbG9yKSwNCiAgIHJhZGl1cyA9IDUsDQogICAgcG9wdXAgPSB+cGFzdGUoIk9iamVjdCBJRDogIiwgb2JqZWN0aWQsDQogICAgICAgICAgICAgICAgICAgIlllYXI6ICIsIHllYXIsDQogICAgICAgICAgICAgICAgICAgIlJhY2U6ICIsIHJhY2UsDQogICAgICAgICAgICAgICAgICAgIlNleDogIiwgc2V4LA0KICAgICAgICAgICAgICAgICAgICJBZ2U6ICIsIGFnZSwNCiAgICAgICAgICAgICAgICAgICAiV291bmQ6ICIsIHdvdW5kLA0KICAgICAgICAgICAgICAgICAgICJMb2NhdGlvbjogIiwgbG9jYXRpb24pLA0KICAgIGxhYmVsT3B0aW9ucyA9IGxhYmVsT3B0aW9ucygNCiAgICAgIGRpcmVjdGlvbiA9ICJhdXRvIg0KICAgICkNCiAgKSAlPiUNCiAgYWRkTGVnZW5kKA0KICAgIHBvc2l0aW9uID0gImJvdHRvbXJpZ2h0IiwNCiAgICBjb2xvcnMgPSBjKGZhdGFsX2NvbG9yLCBub25fZmF0YWxfY29sb3IpLA0KICAgIGxhYmVscyA9IGMoIkZhdGFsIiwgIk5vbi1GYXRhbCIpLA0KICAgIHRpdGxlID0gIkNyaW1lIFR5cGUiDQogICkgJT4lDQogIGFkZFNjYWxlQmFyKCkgJT4lDQogIGFkZENvbnRyb2woDQogICAgaHRtbCA9ICI8aDQ+UGhpbGFkZWxwaGlhIENyaW1lIExvY2F0aW9ucyAoMjAxNS0yMDI0KTwvaDQ+IiwNCiAgICBwb3NpdGlvbiA9ICJ0b3ByaWdodCINCiAgKSU+JQ0KICBzZXRWaWV3KGxuZyA9IC03NS4xNTI3LCBsYXQgPSAzOS45NzA3LCB6b29tID0gMTEpICU+JQ0KICBhZGRQcm92aWRlclRpbGVzKHByb3ZpZGVycyRFc3JpLldvcmxkR3JheUNhbnZhcykgJT4lDQogICAgYWRkUG9seWdvbnMoZGF0YSA9IHBoaWxseU5laWdoYm9yLA0KICAgICAgICAgICAgICBjb2xvciA9ICdza3libHVlJywNCiAgICAgICAgICAgICAgd2VpZ2h0ID0gMSkgICU+JQ0KICBhZGRDaXJjbGVNYXJrZXJzKGRhdGEgPSBwaGlsbHlfc2YsDQogICAgICAgICAgICAgICAgICAgcmFkaXVzID0gNSwNCiAgICAgICAgICAgICAgICAgICBjb2xvciA9IH5wYWwoZmF0YWwpLA0KICAgICAgICAgICAgICAgICAgIHN0cm9rZSA9IEZBTFNFLCANCiAgICAgICAgICAgICAgICAgICBmaWxsT3BhY2l0eSA9IDAuNSwNCiAgICAgICAgICAgICAgICAgICBjbHVzdGVyT3B0aW9ucyA9IG1hcmtlckNsdXN0ZXJPcHRpb25zKG1heENsdXN0ZXJSYWRpdXMgPSA0MCkpICU+JQ0KICAjIEFkZGluZyBpbWFnZXMgdG8gdGhlIG1hcA0KICBhZGRNYXJrZXJzKGxuZyA9IC03NS4xNjUyLCBsYXQgPSAzOS45NTI2LCBwb3B1cCA9ICc8aW1nIHNyYz0iaHR0cHM6Ly9wZW5nZHNjaS5naXRodWIuaW8vU1RBNTUzVklaL3cwOC9QaGlsbHlDaXR5SGFsbC5qcGciIHdpZHRoPSIyMDAiIGhlaWdodD0iMjAwIj4nKSAlPiUNCiAgIyBIVE1MIHN0eWxlIGZvciB0aGUgbWFwIHRpdGxlDQogIGFkZENvbnRyb2woSFRNTCgnPGRpdiBjbGFzcz0ibGVhZmxldC1jb250cm9sLm1hcC10aXRsZSI+UGhpbGFkZWxwaGlhIENyaW1lIExvY2F0aW9ucyAoMjAxNS0yMDI0KTwvZGl2PicpLCBwb3NpdGlvbiA9ICJ0b3ByaWdodCIpICU+JQ0KICBhZGRMYXllcnNDb250cm9sKGJhc2VHcm91cHMgPSBjKCdEYXJrJywgJ0RhcmtMYWJlbCcsICdFc3JpJyksDQogICAgICAgICAgICAgICAgICAgb3ZlcmxheUdyb3VwcyA9IGMoIkNyaW1lIERhdGEiKSwNCiAgICAgICAgICAgICAgICAgICBvcHRpb25zID0gbGF5ZXJzQ29udHJvbE9wdGlvbnMoY29sbGFwc2VkID0gVFJVRSkpDQogIA0KDQojIERpc3BsYXkgdGhlIG1hcA0KbWFwDQpgYGANCg0KDQo=